home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
convrtrs
/
pbmplus
/
hpcd2ppm.lha
/
hpcdtoppm.0.5.pl1
/
src
/
tools.c
< prev
Wrap
C/C++ Source or Header
|
1993-08-20
|
9KB
|
422 lines
/* hpcdtoppm (Hadmut's pcdtoppm) v0.5pl1
* Copyright (c) 1992, 1993 by Hadmut Danisch (danisch@ira.uka.de).
* Permission to use and distribute this software and its
* documentation for noncommercial use and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation. It is not allowed to sell this software in
* any way. This software is not public domain.
*/
#include "hpcdtoppm.h"
void clearimpl(implane *l,sINT n)
{ dim x,y;
uBYTE *ptr;
ptr=l->im;
for (x=0;x<l->mwidth;x++)
for (y=0; y<l->mheight;y++)
*(ptr++)=n;
}
void halve(implane *p)
{dim w,h,x,y;
uBYTE *optr,*nptr;
melde("halve\n");
if ((!p) || (!p->im)) error(E_INTERN);
w=p->iwidth/=2;
h=p->iheight/=2;
for(y=0;y<h;y++)
{
nptr=(p->im) + y*(p->mwidth);
optr=(p->im) + 2*y*(p->mwidth);
for(x=0;x<w;x++,nptr++,optr+=2)
{ *nptr = *optr;
}
}
}
void interpolate(implane *p)
{dim w,h,x,y,yi;
uBYTE *optr,*nptr,*uptr;
melde("interpolate\n");
if ((!p) || (!p->im)) error(E_INTERN);
w=p->iwidth;
h=p->iheight;
if(p->mwidth < 2*w ) error(E_INTERN);
if(p->mheight < 2*h ) error(E_INTERN);
p->iwidth=2*w;
p->iheight=2*h;
for(y=0;y<h;y++)
{yi=h-1-y;
optr=p->im+ yi*p->mwidth + (w-1);
nptr=p->im+2*yi*p->mwidth + (2*w - 2);
nptr[0]=nptr[1]=optr[0];
for(x=1;x<w;x++)
{ optr--; nptr-=2;
nptr[0]=optr[0];
nptr[1]=(((sINT)optr[0])+((sINT)optr[1])+1)>>1;
}
}
for(y=0;y<h-1;y++)
{optr=p->im + 2*y*p->mwidth;
nptr=optr+p->mwidth;
uptr=nptr+p->mwidth;
for(x=0;x<w-1;x++)
{
nptr[0]=(((sINT)optr[0])+((sINT)uptr[0])+1)>>1;
nptr[1]=(((sINT)optr[0])+((sINT)optr[2])+((sINT)uptr[0])+((sINT)uptr[2])+2)>>2;
nptr+=2; optr+=2; uptr+=2;
}
*(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1;
*(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1;
}
optr=p->im + (2*h-2)*p->mwidth;
nptr=p->im + (2*h-1)*p->mwidth;
for(x=0;x<w;x++)
{ *(nptr++) = *(optr++); *(nptr++) = *(optr++); }
}
static sINT testbegin(void)
{sINT i,j;
for(i=j=0;i<32;i++)
if(sbuffer[i]==0xff) j++;
return (j>30);
}
sINT Skip4Base(void)
{sINT cd_offset,cd_offhelp;
cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
SEEK(cd_offset+3);
EREADBUF;
cd_offhelp=((((sINT)sbuffer[510])<<8)|sbuffer[511]) + 1;
cd_offset+=cd_offhelp;
SEEK(cd_offset);
EREADBUF;
while(!testbegin())
{cd_offset++;
EREADBUF;
}
return cd_offset;
}
void planealloc(implane *p, dim width, dim height)
{melde("planealloc\n");
p->iwidth=p->iheight=0;
p->mwidth=width;
p->mheight=height;
p->mp = ( p->im = ( uBYTE * ) malloc (width*height*sizeof(uBYTE)) );
if(!(p->im)) error(E_MEM);
}
static void pastequer(implane *gross,dim px,dim py,implane *klein)
{dim x,y;
uBYTE *von,*nach;
if(px+klein->iwidth > gross->iwidth) error(E_INTERN);
if(py+klein->iheight > gross->iheight) error(E_INTERN);
for(y=0;y<klein->iheight;y++)
{ von=klein->im + y * klein->mwidth;
nach=gross->im + (y+py) * gross->mwidth + px;
for(x=0;x<klein->iwidth;x++)
*(nach++)=*(von++);
}
}
static void pastehead(implane *gross,dim px,dim py,implane *klein)
{dim x,y;
uBYTE *von,*nach;
if(px+klein->iwidth > gross->iwidth) error(E_INTERN);
if(py+klein->iheight > gross->iheight) error(E_INTERN);
for(y=0;y<klein->iheight;y++)
{ von= klein->im + (klein->iheight-1-y) * klein->mwidth + (klein->iwidth - 1);
nach=gross->im + (y+py) * gross->mwidth + px;
for(x=0;x<klein->iwidth;x++)
*(nach++)=*(von--);
}
}
static void pastelinks(implane *gross,dim px,dim py,implane *klein)
{dim x,y;
uBYTE *von,*nach;
if(px+klein->iheight > gross->iwidth) error(E_INTERN);
if(py+klein->iwidth > gross->iheight) error(E_INTERN);
for(y=0;y<klein->iwidth;y++)
{ von=klein->im + klein->iwidth - 1 - y;
nach=gross->im + (y+py) * gross->mwidth + px;
for(x=0;x<klein->iheight;x++,von+=klein->mwidth)
*(nach++)=*(von);
}
}
static void pasterechts(implane *gross,dim px,dim py,implane *klein)
{dim x,y;
uBYTE *von,*nach;
if(px+klein->iheight > gross->iwidth) error(E_INTERN);
if(py+klein->iwidth > gross->iheight) error(E_INTERN);
for(y=0;y<klein->iwidth;y++)
{ von=klein->im + (klein->iheight-1)*klein->mwidth + y;
nach=gross->im + (y+py) * gross->mwidth + px;
for(x=0;x<klein->iheight;x++,von-=klein->mwidth)
*(nach++)=*(von);
}
}
void pastein(implane *gross,
dim xpos,dim xw,
dim ypos,dim yh,
implane *klein, enum TURNS ori)
{
switch (ori)
{
case T_NONE: pastequer(gross,xpos+(xw-klein->iwidth)/2,ypos+(yh-klein->iheight)/2,klein);
break;
case T_LEFT: pastelinks(gross,xpos+(xw-klein->iheight)/2,ypos+(yh-klein->iwidth)/2,klein);
break;
case T_RIGHT:pasterechts(gross,xpos+(xw-klein->iheight)/2,ypos+(yh-klein->iwidth)/2,klein);
break;
case T_HEAD: pastehead(gross,xpos+(xw-klein->iwidth)/2,ypos+(yh-klein->iheight)/2,klein);
break;
case T_AUTO:
default: error(E_INTERN);
}
}
#define cro(p,d) {if(p) {p->im+=d*p->mwidth; p->iheight-=d;}}
#define cru(p,d) {if(p) {p->iheight-=d;}}
#define crl(p,d) {if(p) {p->im+=d; p->iwidth-=d;}}
#define crr(p,d) {if(p) {p->iwidth-=d;}}
void cropit(sizeinfo *si,implane *l,implane *c1,implane *c2)
{dim x,y,s,w,h;
sINT nl,nr,no,nu;
uBYTE *ptr;
melde("crop\n");
if(si->imvlen || si->imhlen) error(E_INTERN);
w=si->rdhlen;
h=si->rdvlen;
if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN);
if(!monochrome)
{if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN);
if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN);
}
for(y=0,no=0;y<h;y++,no++)
{for(x=0,ptr=(l->im)+y*(l->mwidth); x<w && (*ptr)<MAX_BLACK ;x++,ptr++);
if(x<w) break;
}
cro(l ,no);
cro(c1,no);
cro(c2,no);
h-=no;
for(y=h-1,nu=0;y;y--,nu++)
{for(x=0,ptr=(l->im)+y*(l->mwidth); x<w && (*ptr)<MAX_BLACK ;x++,ptr++);
if(x<w) break;
}
cru(l ,nu);
cru(c1,nu);
cru(c2,nu);
h-=nu;
s=l->mwidth;
for(x=0,nl=0;x<w;x++,nl++)
{for(y=0,ptr=(l->im)+x; y<h && (*ptr)<MAX_BLACK ; y++, ptr+=s);
if(y<h) break;
}
crl(l ,nl);
crl(c1,nl);
crl(c2,nl);
w-=nl;
for(x=w-1,nr=0;x;x--,nr++)
{for(y=0,ptr=(l->im)+x; y<h && (*ptr)<MAX_BLACK ; y++, ptr+=s);
if(y<h) break;
}
crr(l ,nr);
crr(c1,nr);
crr(c2,nr);
w-=nr;
if (do_melde)
{
if (no || nu || nr || nl )
fprintf(stderr,"Cut off %d top, %d bottom, %d left, %d right, new size is %ldx%ld\n",
no,nu,nl,nr,w,h);
else
fprintf(stderr,"Nothing cut off\n");
}
si->imvlen=h;
si->imhlen=w;
}
void shrink(sizeinfo *si,implane *l,implane *c1,implane *c2)
{dim w,h;
melde("shrink\n");
w=si->rdhlen;
h=si->rdvlen;
if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN);
if(!monochrome)
{if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN);
if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN);
}
if((!si->imvlen) && (!si->imhlen)) /* no subrectangle given */
{si->imvlen=si->rdvlen;
si->imhlen=si->rdhlen;
return;
}
if (si->imvlen>h || si->imvlen<1 ) error(E_INTERN);
if (si->imvoff> si->rdvlen - si->imvlen) error(E_INTERN);
if (si->imhlen>w || si->imhlen<1 ) error(E_INTERN);
if (si->imhoff> si->rdhlen - si->imhlen) error(E_INTERN);
cro(l ,si->imvoff);
cro(c1,si->imvoff);
cro(c2,si->imvoff);
cru(l ,si->rdvlen - si->imvoff - si->imvlen);
cru(c1,si->rdvlen - si->imvoff - si->imvlen);
cru(c2,si->rdvlen - si->imvoff - si->imvlen);
crl(l ,si->imhoff);
crl(c1,si->imhoff);
crl(c2,si->imhoff);
crr(l ,si->rdhlen - si->imhoff - si->imhlen);
crr(c1,si->rdhlen - si->imhoff - si->imhlen);
crr(c2,si->rdhlen - si->imhoff - si->imhlen);
}
/* Test Data types for their size an whether they
are signed / unsigned */
void typecheck(void)
{ sBYTE sbyte;
uBYTE ubyte;
sINT sint;
uINT uint;
if(sizeof(sBYTE) != 1) error(E_CONFIG);
sbyte=126; sbyte++; sbyte++;
if(sbyte > 126 ) error(E_CONFIG);
if(sizeof(uBYTE) != 1) error(E_CONFIG);
ubyte=126; ubyte++; ubyte++;
if(ubyte < 126 ) error(E_CONFIG);
#ifdef U_TOO_LONG
if(sizeof(sINT) < 4) error(E_CONFIG);
if(sizeof(uINT) < 4) error(E_CONFIG);
#else
if(sizeof(sINT) != 4) error(E_CONFIG);
if(sizeof(uINT) != 4) error(E_CONFIG);
#endif
sint=1; sint--; sint--;
if(sint>1) error(E_CONFIG);
uint=1; uint--; uint--;
if(uint<1) error(E_CONFIG);
}